import { Request, Response } from 'express';
import { AuthRequest } from '@/types';
import menuService from '@/services/system/menu.service';
import { getLogger } from '@/utils/logger';
import ApiResponse from '@/utils/api/api-response.util';
import { Log, BusinessType } from '@/decorators/Log';
import { RepeatSubmit } from '@/decorators/repeatSubmit.decorator';

// 创建模块专用的日志记录器
const consoleLogger = getLogger("menu-controller");
const logger = getLogger("menu-controller", {
	console: false,
});

class MenuController {
  /**
   * 获取菜单列表
   */
  async list(req: Request, res: Response) {
    try {
      const params = {
        ...req.query,
        userId: (req as any).user?.userId
      };
      
      // 请求日志
      consoleLogger.info("获取菜单列表请求", {
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      const menus = await menuService.selectMenuList(params);
      
      // 结果日志
      logger.info("获取菜单列表成功", {
        response: {
          count: menus.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, menus);
    } catch (error: any) {
      consoleLogger.error(`获取菜单列表失败: ${error.message}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '查询失败', 500);
      }
    }
  }

  /**
   * 获取菜单详细信息
   */
  async getInfo(req: Request, res: Response) {
    try {
      const menuId = Number(req.params.menuId);
      
      // 请求日志
      consoleLogger.info("获取菜单详细信息请求", {
        params: req.params,
        menuId,
        operator: req.user?.userName || 'unknown',
      });
      
      const menu = await menuService.selectMenuById(menuId);
      if (!menu) {
        ApiResponse.error(res, '菜单不存在', 404);
        return;
      }
      
      // 结果日志
      logger.info("获取菜单详细信息成功", {
        response: {
          menuId,
          menuName: menu.menuName,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, menu);
    } catch (error: any) {
      consoleLogger.error(`获取菜单详情失败: ${error.message}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '查询失败', 500);
      }
    }
  }

  /**
   * 获取菜单树形结构
   */
  async treeselect(req: Request, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("获取菜单树形结构请求", {
        operator: req.user?.userName || 'unknown',
      });
      
      // 获取菜单列表，不构建树形结构
      const menus = await menuService.selectMenuTreeAll(false);
      // 直接使用buildMenuTreeSelect构建树形结构
      const treeSelect = menuService.buildMenuTreeSelect(menus);
      
      // 结果日志
      logger.info("获取菜单树形结构成功", {
        response: {
          count: menus.length,
          treeCount: treeSelect.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, treeSelect);
    } catch (error: any) {
      consoleLogger.error(`获取菜单树失败: ${error.message}`, {
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '查询失败', 500);
      }
    }
  }

  /**
   * 获取用户菜单树
   */
  async userMenuTree(req: AuthRequest, res: Response) {
    try {
      const userId = req.user?.userId || 1;
      
      // 请求日志
      consoleLogger.info("获取用户菜单树请求", {
        userId,
        operator: req.user?.userName || 'unknown',
      });
      
      const menuTree = await menuService.selectMenusByUserId(userId);
      
      // 结果日志
      logger.info("获取用户菜单树成功", {
        response: {
          userId,
          count: menuTree.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, menuTree);
    } catch (error: any) {
      consoleLogger.error(`获取用户菜单树失败: ${error.message}`, {
        requestData: {
          userId: req.user?.userId,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '查询失败', 500);
      }
    }
  }

  /**
   * 获取前端所需的路由菜单
   */
  async getRouters(req: AuthRequest, res: Response) {
    try {
      const userId = req.user?.userId || 1;
      
      // 请求日志
      consoleLogger.info("获取前端路由菜单请求", {
        userId,
        operator: req.user?.userName || 'unknown',
      });
      
      const routers = await menuService.buildMenus(userId);
      
      // 结果日志
      logger.info("获取前端路由菜单成功", {
        response: {
          userId,
          count: routers.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, routers);
    } catch (error: any) {
      consoleLogger.error(`获取前端路由菜单失败: ${error.message}`, {
        requestData: {
          userId: req.user?.userId,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '查询路由失败', 500);
      }
    }
  }

  /**
   * 获取用户权限标识
   */
  async getPermissions(req: AuthRequest, res: Response) {
    try {
      const userId = req.user?.userId || 1;
      
      // 请求日志
      consoleLogger.info("获取用户权限标识请求", {
        userId,
        operator: req.user?.userName || 'unknown',
      });
      
      const permissions = await menuService.selectPermsByUserId(userId);
      
      // 结果日志
      logger.info("获取用户权限标识成功", {
        response: {
          userId,
          permissionsCount: permissions.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, permissions);
    } catch (error: any) {
      consoleLogger.error(`获取用户权限标识失败: ${error.message}`, {
        requestData: {
          userId: req.user?.userId,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '查询权限失败', 500);
      }
    }
  }

  /**
   * 根据角色ID查询菜单树
   */
  async roleMenuTreeselect(req: Request, res: Response) {
    try {
      const roleId = Number(req.params.roleId);
      
      // 请求日志
      consoleLogger.info("根据角色ID查询菜单树请求", {
        params: req.params,
        roleId,
        operator: req.user?.userName || 'unknown',
      });
      
      const menuTree = await menuService.selectMenuTreeByRoleId(roleId);
      
      // 结果日志
      logger.info("根据角色ID查询菜单树成功", {
        response: {
          roleId,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.successWithoutWrapper(res, menuTree);
    } catch (error: any) {
      consoleLogger.error(`根据角色ID查询菜单树失败: ${error.message}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '查询失败', 500);
      }
    }
  }

  /**
   * 新增菜单
   */
  @RepeatSubmit({ expireSeconds: 5 })
  @Log({ title: '菜单管理', businessType: BusinessType.INSERT })
  async add(req: AuthRequest, res: Response) {
    try {
      const menu = req.body;
      
      // 请求日志
      consoleLogger.info("新增菜单请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      // 设置创建者
      menu.createBy = req.user?.userName || 'admin';
      
      // 新增菜单
      const result = await menuService.insertMenu(menu);
      
      // 结果日志
      logger.info("新增菜单成功", {
        response: {
          menuId: result.menuId,
          menuName: result.menuName,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, result, '新增成功');
    } catch (error: any) {
      consoleLogger.error(`新增菜单失败: ${error.message}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '新增失败', 500);
      }
    }
  }

  /**
   * 修改菜单
   */
  @RepeatSubmit({ expireSeconds: 5 })
  @Log({ title: '菜单管理', businessType: BusinessType.UPDATE })
  async update(req: AuthRequest, res: Response) {
    try {
      const menu = req.body;
      
      // 请求日志
      consoleLogger.info("修改菜单请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      // 设置更新者
      menu.updateBy = req.user?.userName || 'admin';
      
      // 修改菜单
      await menuService.updateMenu(menu);
      
      // 结果日志
      logger.info("修改菜单成功", {
        response: {
          menuId: menu.menuId,
          menuName: menu.menuName,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, '修改成功');
    } catch (error: any) {
      consoleLogger.error(`修改菜单失败: ${error.message}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '修改失败', 500);
      }
    }
  }

  /**
   * 删除菜单
   */
  @RepeatSubmit({ expireSeconds: 5 })
  @Log({ title: '菜单管理', businessType: BusinessType.DELETE })
  async remove(req: Request, res: Response) {
    try {
      const menuId = Number(req.params.menuId);
      
      // 请求日志
      consoleLogger.info("删除菜单请求", {
        params: req.params,
        menuId,
        operator: req.user?.userName || 'unknown',
      });
      
      // 删除菜单
      await menuService.deleteMenuById(menuId);
      
      // 结果日志
      logger.info("删除菜单成功", {
        response: {
          menuId,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, '删除成功');
    } catch (error: any) {
      consoleLogger.error(`删除菜单失败: ${error.message}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error.stack,
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error.message || '删除失败', 500);
      }
    }
  }
}

export default new MenuController();